﻿using AiBLSmartEdu.Module.SmartStockSense.API.DTOs;
using FrameworkCore.DI;

namespace AiBLSmartEdu.Module.SmartStockSense.API;

#nullable disable

/// <summary>
/// 预测提供者
/// </summary>
public class KDJPredictionProvider : IScopedDependency
{
    private int _totalPredictionsToday;
    private int _successfulPredictionsToday;
    private bool _isLastPredictionAccurate;
    private string _nextPredictionResult;

    public PredictTrendDto PredictTrend(List<KDJTechnicalIndicatorDto> kdjDataList)
    {
        DateTime? maxDate = kdjDataList?.OrderByDescending(x =>x.T).Select(x=>x.T).First();
        kdjDataList = kdjDataList?.Where(x => x.T.Value == maxDate)?.ToList();
        // 检查数据是否可用
        if (kdjDataList == null || kdjDataList.Count == 0)
        {
            return new PredictTrendDto
            {
                TotalTodayPredictions = 0,
                TodaysPredictionSuccessRate = 0,
                IsLastPredictionAccurate = false,
                NextPredictionResult = "NoData"
            };
        }
        if (kdjDataList.Count == 1) 
        {
            return new PredictTrendDto
            {
                TotalTodayPredictions = 1,
                TodaysPredictionSuccessRate = 0,
                IsLastPredictionAccurate = null,
                NextPredictionResult = PredictTrend(kdjDataList[0]).ToString()
            };
        }

        for (int i = 1; i < kdjDataList.Count; i++)
        {
            _totalPredictionsToday++;
            var currentData = kdjDataList[i];
            var lastData = kdjDataList[i - 1];

            if (PredictTrend(currentData) == PredictTrend(lastData))
            {
                _successfulPredictionsToday++;
            }
        }

        double successRate = _totalPredictionsToday > 0
            ? Math.Round((double)_successfulPredictionsToday / _totalPredictionsToday * 100, 2)
            : 0;

        _isLastPredictionAccurate = CheckPredictionAccuracy(kdjDataList[kdjDataList.Count - 2], kdjDataList[kdjDataList.Count - 1]);
        _nextPredictionResult = PredictTrend(kdjDataList[kdjDataList.Count - 1]).ToString();

        return new PredictTrendDto
        {
            TotalTodayPredictions = _totalPredictionsToday,
            TodaysPredictionSuccessRate = successRate,
            IsLastPredictionAccurate = _isLastPredictionAccurate,
            NextPredictionResult = _nextPredictionResult
        };
    }

    private TrendPrediction PredictTrend(KDJTechnicalIndicatorDto kdjData)
    {

        if (kdjData.K > kdjData.D)
        {
            return TrendPrediction.Up; // 如果 K 大于 D，返回上涨
        }
        else if (kdjData.K < kdjData.D)
        {
            return TrendPrediction.Down; // 如果 K 小于 D，返回下跌
        }
        else
        {
            return TrendPrediction.Steady; // 如果 K 等于 D，返回持平
        }
    }

    private bool CheckPredictionAccuracy(KDJTechnicalIndicatorDto lastData, KDJTechnicalIndicatorDto currentData)
    {
        return currentData.K != lastData.K;
    }
}